﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;
using System.Data;
using System.Data.OleDb;
using System.Drawing;
using System.Globalization;
using System.Text.RegularExpressions;
using System.Collections;

namespace ESOL.Common
{
    public class CommonFunctions
    {
        public static string GetSelect(string rowCount)
        {
            if (string.IsNullOrEmpty(rowCount) == false && IsNumeric(rowCount))
            {
                return " SELECT TOP " + rowCount + " ";
            }
            return " SELECT ";
        }

        public static bool IsNumeric(string pValue)
        {
            if (pValue == null || pValue.Trim() == "")
            {
                return false;
            }
            string numeric = "-0123456789";
            for (int i = 0; i < pValue.Length; i++)
            {
                string character = pValue.Substring(i, 1);
                if (numeric.IndexOf(character) >= 0)
                {
                    continue;
                }
                else
                {
                    return false;
                }
            }
            return true;
        }

        public static bool IsDecimal(string pValue)
        {
            if (pValue == null || pValue.Trim() == "")
            {
                return false;
            }
            string numeric = "-0123456789.";
            for (int i = 0; i < pValue.Length; i++)
            {
                string character = pValue.Substring(i, 1);
                if (numeric.IndexOf(character) >= 0)
                {
                    continue;
                }
                else
                {
                    return false;
                }
            }
            return true;
        }

        public static decimal ToDecimal(object oValue)
        {
            if (oValue == null)
            {
                return 0;
            }
            if (string.IsNullOrEmpty(oValue.ToString()))
            {
                return 0;
            }
            if (IsDecimal(oValue.ToString()) == false)
            {
                return 0;
            }
            return Convert.ToDecimal(oValue.ToString());
        }

        public static int ToInt32(object oValue)
        {
            if (oValue == null)
            {
                return 0;
            }
            if (string.IsNullOrEmpty(oValue.ToString()))
            {
                return 0;
            }
            if (IsNumeric(oValue.ToString()) == false)
            {
                return 0;
            }
            return Convert.ToInt32(oValue.ToString());
        }

        public static string ToString(object oValue)
        {
            if (oValue == null)
            {
                return "";
            }
            return Convert.ToString(oValue);
        }

        public static object ToObject(object oValue)
        {
            if (oValue == null)
            {
                return null;
            }
            if (oValue.ToString().Trim() == "")
            {
                return null;
            }
            return oValue;
        }

        public static string GetFileExtension(string sFile)
        {
            if (string.IsNullOrEmpty(sFile))
                return null;
            string[] sTemp = sFile.Split('.');
            return sTemp[sTemp.Length - 1];
        }

        public static string GetFileNoExtension(string sFile)
        {
            if (string.IsNullOrEmpty(sFile))
                return null;
            string[] sTemp = sFile.Split('.');
            return sTemp[sTemp.Length - 1];
        }

        public static string GetFilePrefix(string sFullFileName)
        {
            if (string.IsNullOrEmpty(sFullFileName))
                return null;
            string[] sTemp = sFullFileName.Split('\\');
            return sTemp[sTemp.Length - 1];
        }

        public static Stream FileToStream(string fileName)
        {
            // 打开文件 
            FileStream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
            // 读取文件的 byte[] 
            byte[] bytes = new byte[fileStream.Length];
            fileStream.Read(bytes, 0, bytes.Length);
            fileStream.Close();
            // 把 byte[] 转换成 Stream 
            Stream stream = new MemoryStream(bytes);
            return stream;
        }

        public static byte[] FileToByte(string fileName)
        {
            FileInfo fi = new FileInfo(fileName);
            FileStream fs = fi.OpenRead();
            byte[] bytes = new byte[fs.Length];
            fs.Read(bytes, 0, Convert.ToInt32(fs.Length));
            fs.Close();
            return bytes;
        }

        /// <summary>
        ///  Stream转化为文件
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="fileName"></param>
        public static void StreamToFile(Stream stream, string fileName)
        {
            // 把 Stream 转换成 byte[] 
            byte[] bytes = new byte[stream.Length];
            stream.Read(bytes, 0, bytes.Length);
            // 设置当前流的位置为流的开始 
            stream.Seek(0, SeekOrigin.Begin);
            // 把 byte[] 写入文件 
            FileStream fs = new FileStream(fileName, FileMode.Create);
            BinaryWriter bw = new BinaryWriter(fs);
            bw.Write(bytes);
            bw.Close();
            fs.Close();
        }

        public static Image ByteToImage(byte[] param)
        {
            try
            {
                MemoryStream ms = new MemoryStream(param);
                Image returnImage = Image.FromStream(ms);
                return returnImage;
            }
            catch (Exception ex)
            {
                return null;
            }
        }

        public static void ByteToFile(byte[] bytes, string fileName)
        {
            FileStream fs = new FileStream(fileName, FileMode.Create);
            BinaryWriter bw = new BinaryWriter(fs);
            bw.Write(bytes);
            bw.Close();
            fs.Close();
        }

        /// 将图片Image转换成Byte[]
        /// </summary>
        /// <param name="Image">image对象</param>
        /// <param name="imageFormat">后缀名</param>
        /// <returns></returns>
        public static byte[] ImageToByte(Image Image, string Ext)
        {
            if (Image == null) { return null; }
            byte[] data = null;
            using (MemoryStream ms = new MemoryStream())
            {
                using (Bitmap Bitmap = new Bitmap(Image))
                {
                    System.Drawing.Imaging.ImageFormat imageFormat = null;
                    switch (Ext.ToLower())
                    {
                        case "jpeg":
                            imageFormat = System.Drawing.Imaging.ImageFormat.Jpeg;
                            break;
                        case "":
                            imageFormat = System.Drawing.Imaging.ImageFormat.Jpeg;
                            break;
                        case "png":
                            imageFormat = System.Drawing.Imaging.ImageFormat.Png;
                            break;
                    }
                    Bitmap.Save(ms, imageFormat);
                    ms.Position = 0;
                    data = new byte[ms.Length];
                    ms.Read(data, 0, Convert.ToInt32(ms.Length));
                    ms.Flush();
                }
            }
            return data;
        }

        /// <summary>
        /// 判断密码，是否符合密码规则
        /// 密码规则：至少有一个大写字母，一个小写字母，一个数字，一个特殊符号，密码长度最小为8位
        /// </summary>
        /// <param name="password"></param>
        /// <returns></returns>
        public static bool CheckPassword(string password, out string errMsg)
        {
            errMsg = "";
            if (string.IsNullOrEmpty(password))
            {
                errMsg = "密码不能为空";
                return false;
            }
            if (password.Length < 8)
            {
                errMsg = "密码长度至少为8为";
                return false;
            }
            bool pass = false;
            string c = "abcdefghijklmnopqrstuvwxyz";
            for (int i = 0; i < password.Length; i++)
            {
                if (c.Contains(password[i]))
                {
                    pass = true;
                    break;
                }
            }
            if (!pass)
            {
                errMsg = "至少需要包含一个小写字母";
                return false;
            }
            pass = false;
            c = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
            for (int i = 0; i < password.Length; i++)
            {
                if (c.Contains(password[i]))
                {
                    pass = true;
                    break;
                }
            }
            if (!pass)
            {
                errMsg = "至少需要包含一个大写字母";
                return false;
            }
            pass = false;
            c = "0123456789";
            for (int i = 0; i < password.Length; i++)
            {
                if (c.Contains(password[i]))
                {
                    pass = true;
                    break;
                }
            }
            if (!pass)
            {
                errMsg = "至少需要包含一个数字";
                return false;
            }
            pass = false;
            c = "~!@#$%^&*()_+";
            for (int i = 0; i < password.Length; i++)
            {
                if (c.Contains(password[i]))
                {
                    pass = true;
                    break;
                }
            }
            if (!pass)
            {
                errMsg = "至少需要包含一个特殊字符";
                return false;
            }
            return true;
        }

        public static string DateDiff(DateTime DateTime1, DateTime DateTime2)
        {
            string dateDiff = null;
            TimeSpan ts1 = new TimeSpan(DateTime1.Ticks);
            TimeSpan ts2 = new TimeSpan(DateTime2.Ticks);
            TimeSpan ts = ts1.Subtract(ts2).Duration();
            dateDiff = ts.Days.ToString() + "天" + ts.Hours.ToString() + "小時" + ts.Minutes.ToString() + "分钟" + ts.Seconds.ToString() + "秒";
            return dateDiff;
        }

        //验证IP地址格式
        public static bool IPCheck(string sIP)
        {
            string num = "(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)";
            return Regex.IsMatch(sIP, ("^" + num + "\\." + num + "\\." + num + "\\." + num + "$"));
        }

        //验证URL格式
        public bool URLCheck(string sURL)
        {
            return Regex.IsMatch(sURL, @"http(s)?://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?");
        }

        //使用系统自带的图片查看器
        public static void OpenPicViewer(Image img)
        {
            System.Diagnostics.Process process = new System.Diagnostics.Process();
            string fileName = System.IO.Path.GetTempPath() + Guid.NewGuid().ToString() + ".jpg";
            img.Save(fileName);
            process.StartInfo.FileName = fileName;
            process.StartInfo.Arguments = "rundll32.exe C:\\WINDOWS\\system32\\shimgvw.dll,ImageView_Fullscreen";
            process.StartInfo.UseShellExecute = true;
            process.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
            process.Start();
            process.Close();
        }

        //计算某个日期所在的周是当年的第几周
        public static int WeekOfYear(DateTime dt, CultureInfo ci)
        {
            return ci.Calendar.GetWeekOfYear(dt, ci.DateTimeFormat.CalendarWeekRule, ci.DateTimeFormat.FirstDayOfWeek);
        }

        public static DataTable Readxls(string path)
        {
            string strCon = "";
            if (path.Substring(path.Length - 1).Equals("x"))
            {
                strCon = " Provider = Microsoft.ACE.OLEDB.12.0 ; Data Source =" + path + ";Extended Properties=\"Excel 12.0;HDR=YES\"";
            }
            else
            {
                strCon = " Provider = Microsoft.Jet.OLEDB.4.0 ; Data Source =" + path + ";Extended Properties=Excel 8.0";
            }

            OleDbConnection conn = new OleDbConnection(strCon);
            string tableName = "sheet1$";
            conn.Open();
            DataTable dt = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" });
            if (dt != null && dt.Rows.Count > 0)
            {
                tableName = dt.Rows[0]["TABLE_NAME"].ToString();
            }
            string sql = "select * from [" + tableName + "]";
            OleDbDataAdapter cmd = new OleDbDataAdapter(sql, strCon);
            DataSet ds = new DataSet();
            cmd.Fill(ds, "FormObjects");
            conn.Close();
            if (ds != null && ds.Tables.Count > 0)
            {
                return ds.Tables[0];
            }
            return null;
        }

        public static DataTable ReadDwg(string path)
        {
            throw new Exception();
        }

    }

    public class CommonFunction
    {
        /// <typeparam name="T"></typeparam>     
        /// <param name="list"></param>     
        /// <returns></returns>     
        public DataTable ListToDt<T>(IEnumerable<T> list)
        {
            //创建属性的集合     
            List<PropertyInfo> pList = new List<PropertyInfo>();
            //获得反射的入口     

            Type type = typeof(T);
            DataTable dt = new DataTable();
            //把所有的public属性加入到集合 并添加DataTable的列     
            Array.ForEach<PropertyInfo>(type.GetProperties(), p => { pList.Add(p); dt.Columns.Add(p.Name, p.PropertyType); });
            foreach (var item in list)
            {
                //创建一个DataRow实例     
                DataRow row = dt.NewRow();
                //给row 赋值     
                pList.ForEach(p => row[p.Name] = p.GetValue(item, null));
                //加入到DataTable     
                dt.Rows.Add(row);
            }
            return dt;
        }

        public DataTable ToDataTable(IList list)
        {
            DataTable result = new DataTable();
            if (list.Count > 0)
            {
                PropertyInfo[] propertys = list[0].GetType().GetProperties();
                foreach (PropertyInfo pi in propertys)
                {
                    if (pi.PropertyType.IsGenericType)
                    {
                        if (pi.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
                        {
                            if (pi.PropertyType.GetGenericArguments()[0] == typeof(DateTime))
                            {
                                result.Columns.Add(pi.Name, typeof(DateTime));
                            }
                            if (pi.PropertyType.GetGenericArguments()[0] == typeof(int))
                            {
                                result.Columns.Add(pi.Name, typeof(int));
                            }
                        }

                    }
                    else
                    {
                        result.Columns.Add(pi.Name, pi.PropertyType);
                    }
                }


                for (int i = 0; i < list.Count; i++)
                {
                    ArrayList tempList = new ArrayList();
                    foreach (PropertyInfo pi in propertys)
                    {
                        if (pi.PropertyType.Name.Equals("EntitySet`1"))
                            continue;
                        object obj = pi.GetValue(list[i], null);
                        tempList.Add(obj);
                    }
                    object[] array = tempList.ToArray();
                    result.LoadDataRow(array, true);
                }
            }
            return result;
        }

        /// <summary>     
        /// DataTable 转换为List 集合     
        /// </summary>     
        /// <typeparam name="TResult">类型</typeparam>     
        /// <param name="dt">DataTable</param>     
        /// <returns></returns>     
        public List<T> DtToList<T>(DataTable dt) where T : class, new()
        {
            //创建一个属性的列表     
            List<PropertyInfo> prlist = new List<PropertyInfo>();
            //获取TResult的类型实例  反射的入口     

            Type t = typeof(T);

            //获得TResult 的所有的Public 属性 并找出TResult属性和DataTable的列名称相同的属性(PropertyInfo) 并加入到属性列表      
            Array.ForEach<PropertyInfo>(t.GetProperties(), p => { if (dt.Columns.IndexOf(p.Name) != -1) prlist.Add(p); });

            //创建返回的集合     

            List<T> oblist = new List<T>();

            foreach (DataRow row in dt.Rows)
            {
                //创建TResult的实例     
                T ob = new T();
                //找到对应的数据  并赋值     
                prlist.ForEach(p => { if (row[p.Name] != DBNull.Value) p.SetValue(ob, row[p.Name], null); });
                //放入到返回的集合中.     
                oblist.Add(ob);
            }
            return oblist;
        }

        public static M CopyEntityToServiceOutPut<M, T>(T entity) where M : class,new()
        {
            M output = new M();

            //创建一个属性的列表     
            List<PropertyInfo> prlist = new List<PropertyInfo>();
            //获取TResult的类型实例  反射的入口     

            Type m = typeof(M);
            Type t = entity.GetType();
            string fieldName = "";
            foreach (PropertyInfo outputProperty in m.GetProperties())
            {
                fieldName = outputProperty.Name;
                foreach (PropertyInfo inputProperty in t.GetProperties())
                {
                    if (inputProperty.Name.Equals(fieldName) && inputProperty.CanWrite && !inputProperty.PropertyType.Name.Equals("Object"))
                    {
                        outputProperty.SetValue(output, inputProperty.GetValue(entity, null), null);
                        break;
                    }
                }
            }



            return output;
        }
    }

}
